package com.sibu.yx.promotion.service.biz;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.ServiceException;
import com.aliyun.oss.model.ObjectMetadata;
import com.doubo.common.util.ExceptionUtil;
import com.doubo.common.util.StringUtil;
import com.sibu.yx.promotion.service.config.AliYunOssProperties;

import lombok.extern.slf4j.Slf4j;

/**
 * @author suzheng
 * @date 2021-07-02
 **/
@Slf4j
@Component
public class AliYunOssBiz {

    @Autowired
    private AliYunOssProperties aliYunOssProperties;

    private static final String HTTP = "https://";
    /**
     * @param file
     * @param type
     * @return
     */
    public String uploadFile(File file, String type) throws FileNotFoundException {
        if (file != null) {
            try {
                InputStream ins = new FileInputStream(file);
                return uploadFileByStream(ins, type,null);
            } catch (FileNotFoundException e) {
                log.error("upload file has a error={}", ExceptionUtil.getAsString(e));
                throw  e;
            }
        }
        return null;
    }

    public String getImagePath(String imageUrl) {
        if (imageUrl != null && !(imageUrl = imageUrl.trim()).isEmpty() && !imageUrl.startsWith("http")) {
            return "https://"+aliYunOssProperties.getCdnsUrl() + (imageUrl.startsWith("/") ? imageUrl : "/" + imageUrl);
        }
        return imageUrl;
    }

    /**
     * @param file
     * @param type
     * @return
     */
    public String uploadFile(File file, String type, Map<String,String> userMetadata) {
        if (file != null) {
            try {
                InputStream ins = new FileInputStream(file);
                return uploadFileByStream(ins, type, userMetadata);
            } catch (FileNotFoundException e) {
                log.error("upload file has a error={}", ExceptionUtil.getAsString(e));
            }
        }
        return null;
    }

    /**
     * 上传bytes数组字节
     *
     * @param bytes
     * @return
     */
    public String uploadFileByBytes(byte[] bytes, String type, Map<String,String> userMetadata) {
        if (StringUtil.isNull(bytes) || bytes.length <= 0) {
            throw new ServiceException("bytes  can not be  null");
        }
        try {
            InputStream inputStream = new ByteArrayInputStream(bytes);
            return this.uploadFileByStream(inputStream, type,userMetadata);
        } catch (Exception ex) {
            log.error("upload file by url has a error", ex);
            throw new ServiceException(ex.getMessage());
        }
    }

    /**
     * 上传文件
     *
     * @param inputStream
     * @return
     */
    public String uploadFileByStream(InputStream inputStream, String type,Map<String,String> userMetadata) {
        if (inputStream == null) {
            log.error("input stream can not be null");
            return null;
        }
        OSSClient ossClient = new OSSClient(HTTP + aliYunOssProperties.getEndpoint(),
                aliYunOssProperties.getAccessKeyId(), aliYunOssProperties.getAccessKeySecret());
        try {
            String fileName = this.createFileName() + "." + type;
            ObjectMetadata objectMetadata = new ObjectMetadata();
            if(userMetadata != null){
                objectMetadata.setUserMetadata(userMetadata);
            }
            ossClient.putObject(aliYunOssProperties.getBucketName(), fileName, inputStream, objectMetadata);
            inputStream.close();
            return HTTP + aliYunOssProperties.getCdnsUrl() + "/" + fileName;
        } catch (Exception e) {
            log.error("upload file has a error={}", ExceptionUtil.getAsString(e));
        } finally {
            ossClient.shutdown();
        }
        return null;
    }

    /**
     * 上传文件
     *
     * @param fileName
     * @return
     */
    public Map<String, String> getFileObjectMeta(String fileName) {
        OSSClient ossClient = null;
        try {
             ossClient = new OSSClient(HTTP + aliYunOssProperties.getEndpoint(),
                    aliYunOssProperties.getAccessKeyId(), aliYunOssProperties.getAccessKeySecret());
            ObjectMetadata objectMetadata = ossClient.getObjectMetadata(aliYunOssProperties.getBucketName(), fileName);
            return objectMetadata.getUserMetadata();
        } catch (OSSException e) {
            log.error("upload file has a error={}", ExceptionUtil.getAsString(e));
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }

    private String createFileName() {
        // 文件名
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 上传网络文件
     *
     * @param url
     * @return
     */
    public String uploadFileByUrl(String url) {
        if (StringUtil.isNull(url)) {
            throw new ServiceException("upload url  can not be  null");
        }
        try {
            InputStream inputStream = new URL(url).openStream();
            return this.uploadFileByStream(inputStream, null,null);
        } catch (Exception ex) {
            log.error("upload file by url has a error", ex);
            throw new ServiceException(ex.getMessage());
        }
    }

    /**
     * 上传bytes数组字节
     *
     * @param bytes
     * @return
     */
    public String uploadFileByBytes(byte[] bytes, String type) {
        if (StringUtil.isNull(bytes) || bytes.length <= 0) {
            throw new ServiceException("bytes  can not be  null");
        }
        try {
            InputStream inputStream = new ByteArrayInputStream(bytes);
            return this.uploadFileByStream(inputStream, type,null);
        } catch (Exception ex) {
            log.error("upload file by url has a error", ex);
            throw new ServiceException(ex.getMessage());
        }
    }

}
